﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using Scripter.Interpreter;

namespace LowLevelGraphics.Filter
{
    public class InterpretedFilter : BaseImageFilter
    {
        private RuntimeInterpreter runtimeInterpreter = null;
        private string m_sScript = string.Empty;

        private static string sLibraryPath = Application.StartupPath + @"\LowLevelGraphics.dll";

        private Assembly assembly = Assembly.LoadFrom(sLibraryPath);

        public InterpretedFilter()
        {
        }

        public InterpretedFilter(IFilter _filter)
        {
            m_sScript = GetInsertStatementFromFilter(_filter);
        }

        public InterpretedFilter(string _sScript)
        {
            this.m_sScript = _sScript;
        }

        internal InterpretedFilter(InterpretedFilter _interpretedFilter)
        {
            this.m_sScript = _interpretedFilter.m_sScript;
        }

        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            return ExecuteInterpretedScript(_bitmap, m_sScript);
        }

        public string Script
        {
            get { return m_sScript; }
            set { m_sScript = value; }
        }

        private UnsafeBitmap ExecuteInterpretedScript(UnsafeBitmap bitmap, string _sScriptToInterpret = null)
        {
            string sSource = string.Empty;

            runtimeInterpreter = new RuntimeInterpreter(_sScriptToInterpret, assembly);
            runtimeInterpreter.Bitmap = bitmap;
            runtimeInterpreter.Interpret();

            return runtimeInterpreter.Bitmap;
        }

        public static string GetInsertStatementFromFilter(IFilter filter)
        {
            PropertyInfo[] aInfo = filter.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

            string sParam = string.Empty;
            foreach (PropertyInfo info in aInfo)
            {
                object oValue = info.GetValue(filter, null);
                sParam += string.Format("{0}={1}", info.Name, oValue) + " ";
            }

            string sCommandString = string.Format("{0} {1}", filter.GetType().Name, sParam);
            return sCommandString;
        }

        public override object Clone()
        {
            return new InterpretedFilter(this);
        }
    }
}
